/*
 * Example daemon shell code for all of the requirements of a basic
 * linux daemon written in C.
 *
 * To use this code, search for 'TODO' and follow the directions.
 * 
 * To compile this file:
 *      gcc -o [daemonname] thisfile.c
 *
 * Substitute gcc with cc on some platforms.
 *
 * Peter Lombardo (peter AT lombardo DOT info)
 * 5/1/2006
 *
 */
 
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <assert.h>
#include <signal.h>

#include "options.h"
#include "light_beat.h"
 
void signal_handler(int sig) {
 
        switch(sig) {
        case SIGHUP:
                syslog(LOG_WARNING, "Received SIGHUP signal.");
                break;
        case SIGTERM:
                syslog(LOG_WARNING, "Received SIGTERM signal.");
                break;
        case SIGINT:
                syslog(LOG_WARNING, "Quitting since we received SIGINT.");
                exit(2);
                break;
        default:
                syslog(LOG_WARNING, "Unhandled signal (%d) %s", sig, "t");
                /*strsignal(sig));*/
                break;
    }
}

void writepid(lightoptions * opts)
{
        FILE * pid = fopen(opts->pidfile, "w+");
        if (pid == NULL) {
                fprintf(stderr, "Could not write to pid file!\n");
        }
        fprintf(pid, "%d\n", getpid());
        fclose(pid);
}
 
int main(int argc, char *argv[]) {

        lightoptions *opts = get_options(argc, argv);
 
        // Setup signal handling before we start
        signal(SIGHUP, signal_handler);
        signal(SIGTERM, signal_handler);
        signal(SIGINT, signal_handler);
        signal(SIGQUIT, signal_handler);

        syslog(LOG_INFO, "%s daemon starting up", DAEMON_NAME);
 
        if (opts->debug) {
                setlogmask(LOG_UPTO(LOG_DEBUG));
                openlog(DAEMON_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
        }
        else {
                setlogmask(LOG_UPTO(LOG_INFO));
                openlog(DAEMON_NAME, LOG_CONS, LOG_USER);
        }
 
        /* Our process ID and Session ID */
        pid_t pid, sid;
        int fd;

        if (opts->daemonmode) {
                syslog(LOG_INFO, "starting the daemonizing process");
 
                /* Fork off the parent process */
                pid = fork();
                if (pid < 0) {
                        exit(EXIT_FAILURE);
                }
                /* If we got a good PID, then
                   we can exit the parent process. */
                if (pid > 0) {
                        exit(EXIT_SUCCESS);
                }
 
                /* Change the file mode mask */
                umask(0);
 
                /* Create a new SID for the child process */
                sid = setsid();
                if (sid < 0) {
                        /* Log the failure */
                        exit(EXIT_FAILURE);
                }
 
                /* Change the current working directory */
                if ((chdir("/")) < 0) {
                        /* Log the failure */
                        exit(EXIT_FAILURE);
                }
 
                /* Close out the standard file descriptors */

                close(STDIN_FILENO);
                close(STDOUT_FILENO);
                close(STDERR_FILENO);
                if (opts->logfile != NULL) {
                        fd = 0;
                        while (fd < STDERR_FILENO && fd != -1) {
                                fd = open(opts->logfile, O_APPEND | O_CREAT);
                        }
                }
                writepid(opts);
        }

        runlight(opts);
        syslog(LOG_INFO, "%s daemon exiting", DAEMON_NAME);

        free(opts);
        exit(0);
}
